package chat;

import java.net.*;
import java.io.*;

import MainGUI.MainServerGUI;

/**
 * Chat Server class for CS313 ACE4. Spawns separate threads
 * for each client that connects. Keeps track of session number
 * as a unique identifier for each thread and a number of connections
 * made.
 * @author derykegan
 *
 */

public class ChatServer extends Thread{
	
	private int socket;
	private String serverName;
	private SyncChat messages;
	
	private boolean listening = true;
	private boolean standalone;
	
	MainServerGUI gui;
	
	public ChatServer(int socket, String serverName) throws IOException{
		
		/* set up socket and server name */
		this.socket = socket;
		this.serverName = serverName;
		this.messages = new SyncChat();
		
		standalone = true;
		
		run();
	}
	
	/**
	 * Creates a server with a reference to GUI to do updates.
	 * @param socket
	 * @param serverName
	 * @param gui
	 * @throws IOException
	 */
	public ChatServer(int socket, String serverName, MainServerGUI gui) throws IOException{
		
		/* set up socket and server name */
		this.socket = socket;
		this.serverName = serverName;
		this.messages = new SyncChat();
		this.gui = gui;
		
		standalone = false;
	}
	
	public void run(){
		
		/* Set up server and client sockets */
		ServerSocket serverSocket = null;
		
		try{
			serverSocket = new ServerSocket(socket);
			writeUpdate("CHAT SERVER STARTED.\nMessages from " +
					"main server thread are prefixed with star (*)\n");
		}
		catch(IOException e){
			writeUpdate("* Unable to establish server socket, error: " + e);
			System.exit(1);
		}
		
        Socket clientSocket = null;
        int sessionCount = 1;
        /* listen for connections */
        while(listening){
        	writeUpdate("* Listening on port " + socket + "...");
        	
        	try {
        		/* on socket accept */
        		clientSocket = serverSocket.accept();
        		writeUpdate("* Connection established. Session ID: " + sessionCount);
        		
        		if(!standalone){
        			/* spawn new server thread and execute */
        			new ChatThread(clientSocket, 
        					sessionCount, 
        					serverName, 
        					messages, 
        					gui,
        					false)
        			.start();
        		}
        		else{
        			/* spawn new server thread and execute */
        			new ChatThread(clientSocket, 
        					sessionCount, 
        					serverName, 
        					messages, 
        					false)
        			.start();
        		}
        		
        		/* increment session counter */
        		sessionCount++;
        		
        	} 
        	
        	catch (IOException e) {
        		System.out.println("* Error establishing connection: " + e);
        		System.exit(1);
        	}
        	
        	

        }
        
  	  /* cleanup */
        clientSocket = null;
        try {
			serverSocket.close();
		} catch (IOException e) {
			System.out.println(e.toString());
		}
		
	}
	
	/**
	 * Private update method to write strings to either console or
	 * GUI.
	 * @param update
	 */
	
	private void writeUpdate(String update){
		if(standalone)
			System.out.println(update);
		else
			gui.updateChatString(update + "\n");
	}
	
	/**
	 * Close server.
	 */
	public void shutDown(){
		listening = false;
	}

}
